local Util = require("app.utils.Util")

local DesktopModel = class("DesktopModel")

function DesktopModel:ctor() 
    Constant.MENU_MAX_NUM = tonumber(S("menumaxbuttons"))
    if not Constant.MENU_MAX_NUM then
        Constant.MENU_MAX_NUM = 7
    end

    self.mTaskFinish = nil

    -- 需要排序的集合
    self._positions = {
        bottomPosition = {1,2,3,4,5,6,7,8},
        bottomSecPosition = {9,10,11,12,13,14,15,16},
        topPosition = {21,22,23,24,25,26,27,28,29,30,31,32,33,34,35},
        rightPosition = {40,41,42,43,44,45,46},
        leftTopPosition = {50,51},
        leftPosition = {60},
        rightTopPosition = {71,72,73}
    }

    -- 功能开放的配置
    self:initFuncConf()
end

function DesktopModel:initFuncConf()
    -- 开放的功能id
    self.funcIds = {} 

    self._bottomFuncIds = {}

    -- 已开放排序的funcParams
    self._bottomFuncParams = {}
    self._topFuncParams = {}
    self._rightFuncParams = {}
    self._rightTopFuncParams = {}

    self._allFuncParamsDict = {}

    local confs = self._confs
    if not confs then
        local numConfs = {}
        confs = GD:queryFeatureOn()
        for k,conf in pairs(confs) do
            numConfs[tonumber(k)] = conf
        end
        confs = numConfs
        self._confs = numConfs
    end

    local isDebug = DEBUG > 0
    local lev = UD:getLevel()
    for id,conf in pairs(confs) do
        if self:_canCheckFunctionOpen(id, conf) then
            if isDebug then
                self:addFuncId(id)
            else
                if conf.questId then
                    local questId = tonumber(conf.questId)
                    if UD:isMainTaskFinished(questId) then
                        self:addFuncId(id)
                    end
                end
                if conf.level then
                    local level = tonumber(conf.level)
                    if level <= lev then
                        self:addFuncId(id)
                    end
                end
            end
        end
    end
    -- 默认开放
    for i = 1000,1010 do
        self:addFuncId(i)
    end
    for i = 2000,2010 do
        self:addFuncId(i)
    end

    for _,funcId in pairs(self.funcIds) do
        self:_addOpenFunc(funcId)
    end

    

    self:_sortFuncParams(self._bottomFuncParams, self._positions.bottomPosition)
    self:_sortFuncParams(self._topFuncParams, self._positions.topPosition)
    self:_sortFuncParams(self._rightFuncParams, self._positions.rightPosition)
    self:_sortFuncParams(self._rightTopFuncParams, self._positions.rightTopPosition)

    -- dump(self.funcIds, "self.funcIds")
    -- dump(self._bottomFuncParams, "self._bottomFuncParams")
    -- dump(self._topFuncParams, "self._topFuncParams")
    -- dump(self._rightFuncParams, "self._rightFuncParams")
    -- dump(self._rightTopFuncParams, "self._rightTopFuncParams")
end

function DesktopModel:_addOpenFunc(funcId, isNew, iconPathData)
    isNew = isNew or false
    local config = self._confs[funcId]
    if config and config.pos and config.pos ~= "0" then
        local pos = tonumber(config.pos)
        local name = L(config.name)
        local params = {funcId=funcId, pos=pos, name=name }
        --针对动态创建的图 需要记录下iconname
        if iconPathData then
            params.iconPath = iconPathData
        end

        if self:isBottomPos(pos) then
            table.insert(self._bottomFuncIds, funcId)
            table.insert(self._bottomFuncParams, params)
            if isNew then
                self:_sortFuncParams(self._bottomFuncParams, self._positions.bottomPosition)
            end
        elseif self:isTopPos(pos) then
            table.insert(self._topFuncParams, params)
            if isNew then
                self:_sortFuncParams(self._topFuncParams, self._positions.topPosition)
            end
        elseif self:isRightPos(pos) then
            table.insert(self._rightFuncParams, params)
            if isNew then
                self:_sortFuncParams(self._rightFuncParams, self._positions.rightPosition)
            end
        elseif self:isRightTopPos(pos) then
            table.insert(self._rightTopFuncParams, params)
            if isNew then
                self:_sortFuncParams(self._rightTopFuncParams, self._positions.rightTopPosition)
            end
        else

        end
        self._allFuncParamsDict[funcId] = params
    end
end

function DesktopModel:_removeOpenFunc(funcId)
    local config = self._confs[funcId]
    if config and config.pos and config.pos ~= "0" then
        local pos = tonumber(config.pos)
        if self:isBottomPos(pos) then
            table.removebyvalue(self._bottomFuncIds, funcId)
            for i,param in ipairs(self._bottomFuncParams) do
                if param.funcId == funcId then
                    table.remove(self._bottomFuncParams, i)
                    self:_sortFuncParams(self._bottomFuncParams, self._positions.bottomPosition)
                    break
                end
            end

        elseif self:isTopPos(pos) then
            for i,param in ipairs(self._topFuncParams) do
                if param.funcId == funcId then
                    table.remove(self._topFuncParams, i)
                    self:_sortFuncParams(self._topFuncParams, self._positions.topPosition)
                    break
                end
            end
        elseif self:isRightPos(pos) then
            for i,param in ipairs(self._rightFuncParams) do
                if param.funcId == funcId then
                    table.remove(self._rightFuncParams, i)
                    self:_sortFuncParams(self._rightFuncParams, self._positions.rightPosition)
                    break
                end
            end
        elseif self:isRightTopPos(pos) then
            for i,param in ipairs(self._rightTopFuncParams) do
                if param.funcId == funcId then
                    table.remove(self._rightTopFuncParams, i)
                    self:_sortFuncParams(self._rightTopFuncParams, self._positions.rightTopPosition)
                    break
                end
            end
        else

        end
        self._allFuncParamsDict[funcId] = nil
    end
end


function DesktopModel:_sortFuncParams(funcParams, positions)
    table.sort(funcParams, function(a,b) 
        return a.pos < b.pos
    end)
    for i,v in ipairs(funcParams) do
        v.atPos = positions[i]
    end
end

function DesktopModel:getOpenFuncParamsDict()
    return self._allFuncParamsDict
end

function DesktopModel:getOpenFuncIds()
    return self.funcIds
end

function DesktopModel:getFuncConfs()
    return self._confs
end



function DesktopModel:_canCheckFunctionOpenDetail(id, conf)
    --print("_canCheckFunctionOpenDetail  FUNC_TYPE_OVERSEA_CUSTOMER_SERVICE", id == Constant.FUNC_TYPE_OVERSEA_CUSTOMER_SERVICE, app:getCurrentLanguage())
    if Constant.FUNC_TYPE_MSDK_COMMUNITY == id then
        if UD.msdkData:isFunctionEnable() and not UD.msdkData:isNotTencentChannel() then
            return true
        end
    elseif Constant.FUNC_TYPE_MSDK_QQ == id then
        if UD.msdkData:isEnableShowQQGameCenterView() then
            return true
        end
    elseif Constant.FUNC_TYPE_MSDK_QQ_VIP == id then
        if UD.msdkData:isEnableShowQQGameCenterView() then
            return true
        end
    elseif Constant.FUNC_TYPE_MSDK_WX == id then
        if UD.msdkData:isEnableShowWXGameCenterView() then
            return true
        end
    elseif Constant.FUNC_TYPE_REWARD_CDKEY == id then
        return UD.msdkData:isFunctionEnable() and UD.msdkData:isNotTencentChannel()
    elseif Constant.FUNC_TYPE_OVERSEA_ACCOUNT_UYPGRADE == id then
        if app.channelAPI:isGuest() then
            return true
        end
    else
        return true
    end
    return false
end

function DesktopModel:_canCheckFunctionOpen(id, conf)
    -- 服务器动态判定
    if UD:isFeatureClosedByServer(id) then
        return false
    end

    -- 平台判定
    local publisher = app:getInnerPublisher()
    if string.isContain(conf.publisher, publisher) then
        return self:_canCheckFunctionOpenDetail(id, conf)
    end
    return false
end

function DesktopModel:updateFuncByLev(oldLev, newLev)
    local funcIds = {}
    for k,conf in pairs(self._confs) do
        if self:_canCheckFunctionOpen(k, conf) then
            local level = tonumber(conf.level or 0)
            if level > oldLev and level <= newLev then
                local funcId = tonumber(k)
                self:addFuncId(funcId, true)
                funcIds[#funcIds + 1] = funcId
            end
        end
    end
    return funcIds
end

function DesktopModel:updateFuncByTask(taskId)
    local funcIds = {}
    for k,conf in pairs(self._confs) do
        if self:_canCheckFunctionOpen(k, conf) then
            if conf.questId and tonumber(conf.questId) == taskId then
                local funcId = tonumber(k)
                self:addFuncId(funcId, true)
                funcIds[#funcIds + 1] = funcId
            end
        end
    end
    return funcIds
end

-- 服务器控制功能开发
function DesktopModel:updateFuncByServer(funcId, isClose)
    local ret = false
    if isClose then
        ret = self:removeFuncId(funcId)
    else
        local conf = self._confs[funcId]
        if self:_canCheckFunctionOpen(funcId, conf) then
            if isDebug then
                ret = self:addFuncId(funcId, true)
            else
                if conf.questId then
                    local questId = tonumber(conf.questId)
                    if UD:isMainTaskFinished(questId) then
                        ret = self:addFuncId(funcId, true)
                    end
                end
                if conf.level then
                    local level = tonumber(conf.level)
                    if level <= UD:getLevel() then
                        ret = self:addFuncId(funcId, true)
                    end
                end
            end
        end
    end
    return ret
end

function DesktopModel:addFuncId(funcId, isNew, iconPath, ignoreGuide)
    if self.funcIds[funcId] then 
        --若iconpath存在 需要更新
        local param = self._allFuncParamsDict[funcId]
        if param then
            param.iconPath = iconPath
        end
        return false 
    end

    self.funcIds[funcId] = funcId
    if isNew then
        self:_addOpenFunc(funcId, isNew, iconPath)
        if not ignoreGuide then
            EM:notify("onFunctionOpen", funcId)
        end
    end
    return true
end

function DesktopModel:removeFuncId(funcId)
    if self.funcIds[funcId] then
        self.funcIds[funcId] = nil
        self:_removeOpenFunc(funcId)
        EM:notify("onFunctionClose", funcId)
        return true
    else
        return false
    end
end

function DesktopModel:removeDesktopFuncId(funcId)
    if self.funcIds[funcId] then
        self:_removeOpenFunc(funcId)
        return true
    else
        return false
    end
end

function DesktopModel:addDesktopFuncId(funcId, isNew, iconPathData)
    if self.funcIds[funcId] then
        self:_addOpenFunc(funcId, isNew, iconPathData)
        return true
    else
        return false
    end
end

function DesktopModel:isFuncOpen(funcId)
    return self.funcIds[funcId] ~= nil
end

function DesktopModel:getTopFuncNum()
    return #self._topFuncParams
end

-- top funcs has at least one new
function DesktopModel:isTopFuncHasNew()
    local badge = UD.badge
    local redPoint = UD.redPoint
    for i,v in ipairs(self._topFuncParams) do
        if redPoint:hasKey(v.funcId) then
            if redPoint:getStateByKey(v.funcId) then
                return true
            end
        else
            local badgeNum = badge:getNum(v.funcId)
            if badgeNum > 0 then
                return true
            end
        end
    end
    return false
end

function DesktopModel:getFunctionOpenCondition(funcId)
    local conf = self._confs[funcId]
    if not conf then return L("lua_code_text_430") .. funcId end

    if conf.questId then
        local taskConf = GD:queryTaskById(conf.questId)
        if taskConf then
            return string.format(L("afterFinishTask"), L(taskConf.name))
        end
    end

    return string.format(L("lua_code_text_5"), conf.level)
end

function DesktopModel:isBottomPos(pos)
    return table.hasvalue(self._positions.bottomPosition, pos)
end
function DesktopModel:isTopPos(pos)
    return table.hasvalue(self._positions.topPosition, pos)
end
function DesktopModel:isRightPos(pos)
    return table.hasvalue(self._positions.rightPosition, pos)
end
function DesktopModel:isRightTopPos(pos)
    return table.hasvalue(self._positions.rightTopPosition, pos)
end

-- 获取功能真实的位置
function DesktopModel:getFuncRealPos(funcId)
    local params = self._allFuncParamsDict[funcId]
    if params then
        return params.atPos or params.pos
    end
end

-- 底部btn的开放配置
function DesktopModel:getBottomFunc(funcId)
    for i,v in ipairs(self._bottomFuncParams) do
        if v.functionId == funcId then
            return v
        end
    end
end

function DesktopModel:hasBottomFunc()
    return #self._bottomFuncParams > 0
end

function DesktopModel:saveTaskFinish(taskFinish)
    self.mTaskFinish = taskFinish
end

function DesktopModel:getTaskFinish()
    return self.mTaskFinish
end

function DesktopModel:clearTaskFinish()
    self.mTaskFinish = nil
end

function DesktopModel:isBottomHaveNew()
    local redPoint = UD.redPoint
    for _,funcId in pairs(self._bottomFuncIds) do
        if redPoint:hasKey(funcId) then
            if redPoint:getStateByKey(funcId) then
                return true
            end
        else
            local num = UD.badge:getNum(funcId)
            if num > 0 then 
                return true
            end
        end
    end
    return false
end

function DesktopModel:isBottomSecHaveNew()
    return UD.badge:getNum(Constant.FUNC_TYPE_AVATAR_SHOP) > 0
end

return DesktopModel 
